/**
 * SWT Table 处理工具类使用说明：
 * 1. 主要用于安全创建和操作SWT的Table控件，避免空指针和控件已释放导致的异常
 * 2. 核心功能：表格创建、表头设置、数据操作、样式控制、权限管理
 * 3. 使用前需确保父容器Composite有效（非null且未disposed）
 * 4. 表格行高设置通过字体间接实现，不依赖setItemHeight方法
 * 5. 示例代码：
 *    Composite parent = ...;
 *    String[] headers = {"ID", "名称", "类型"};
 *    // 创建带滚动的表格，默认显示5行
 *    ScrolledComposite scroll = SwtTableHdl.createTableWithScroll(parent, headers, 5, SWT.NONE);
 *    Table table = (Table) scroll.getContent();
 *    // 添加数据
 *    SwtTableHdl.addRow(table, new String[]{"1", "测试数据", "string"});
 *    // 设置列宽
 *    SwtTableHdl.setColumnWidth(table, 0, 80);
 */
package maxinshiSomeipTool20.common.itfSafeSWT;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.*;

/**
 * SWT Table 处理工具类
 * 封装表格创建、样式设置、数据操作、权限控制等功能，提供安全的表格交互接口
 */
public class SwtTableHdl {

    // ====================== 1. 表格创建与初始化 ======================

    /**
     * 创建带滚动条的表格（默认样式：可编辑、多行选择、全选）
     * @param parent 父容器
     * @param headerTexts 表头文本数组（决定列数）
     * @param defaultRowCount 默认显示行数（影响初始高度）
     * @param style 额外样式（如 SWT.SINGLE=单行选择，默认 SWT.MULTI | SWT.FULL_SELECTION | SWT.BORDER）
     * @return 包含表格的滚动容器（便于直接添加到界面）
     */
    public static ScrolledComposite createTableWithScroll(Composite parent, String[] headerTexts, 
                                     int defaultRowCount, int style) {
        if (parent == null || parent.isDisposed() || headerTexts == null || headerTexts.length == 0) {
            return null;
        }

        // 创建滚动容器
        ScrolledComposite scroll = SwtGuiComm.createScrolledComposite(parent, SWT.H_SCROLL | SWT.V_SCROLL);

        // 创建表格（组合默认样式和用户样式）
        int finalStyle = SWT.MULTI | SWT.FULL_SELECTION | SWT.BORDER | style;
        Table table = new Table(scroll, finalStyle);
        table.setHeaderVisible(true); // 显示表头
        table.setLinesVisible(true);  // 显示网格线

        // 设置表头
        setTableHeaders(table, headerTexts);

        // 设置初始高度（基于默认行数）
        setTableDefaultRowCount(table, defaultRowCount);

        // 绑定表格到滚动容器
        scroll.setContent(table);
        SwtGuiComm.refreshLayout(scroll);

        return scroll;
    }

    /**
     * 为表格设置表头
     * @param table 目标表格
     * @param headerTexts 表头文本数组
     */
    public static void setTableHeaders(Table table, String[] headerTexts) {
        if (table == null || table.isDisposed() || headerTexts == null) {
            return;
        }

        // 清除现有表头
        TableColumn[] existingColumns = table.getColumns();
        for (TableColumn col : existingColumns) {
            safeDisposeTableColumn(col);
        }

        // 创建新表头
        for (String text : headerTexts) {
            TableColumn column = new TableColumn(table, SWT.LEFT);
            column.setText(text == null ? "" : text);
            column.pack(); // 初始宽度适应内容
        }
    }

    /**
     * 设置表格默认显示行数（影响表格高度）
     * @param table 目标表格
     * @param rowCount 行数（最小1行）
     */
    public static void setTableDefaultRowCount(Table table, int rowCount) {
        if (table == null || table.isDisposed()) {
            return;
        }

        int validRowCount = Math.max(1, rowCount);
        // 通过字体高度计算行高（避免使用setItemHeight）
        int baseRowHeight = getRowHeightByFont(table);
        Point itemSize = new Point(0, baseRowHeight);
        
        // 设置表格高度（行高 * 行数 + 表头高度 + 边框）
        GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false);
        gridData.heightHint = itemSize.y * validRowCount + 30; // 30为表头和边框预留高度
        table.setLayoutData(gridData);
    }


    // ====================== 2. 表格样式设置 ======================

    /**
     * 设置表格列宽
     * @param table 目标表格
     * @param columnIndex 列索引（从0开始）
     * @param width 宽度（像素，最小50）
     */
    public static void setColumnWidth(Table table, int columnIndex, int width) {
        if (table == null || table.isDisposed() || columnIndex < 0) {
            return;
        }

        TableColumn[] columns = table.getColumns();
        if (columnIndex >= columns.length) {
            return;
        }

        columns[columnIndex].setWidth(Math.max(50, width));
    }

    /**
     * 设置表格所有列宽相同
     * @param table 目标表格
     * @param width 统一宽度
     */
    public static void setUniformColumnWidth(Table table, int width) {
        if (table == null || table.isDisposed()) {
            return;
        }

        int validWidth = Math.max(50, width);
        for (TableColumn column : table.getColumns()) {
            column.setWidth(validWidth);
        }
    }

    /**
     * 设置表格行高（通过字体间接设置，避免使用setItemHeight）
     * @param table 目标表格
     * @param height 行高（像素，最小20）
     */
    public static void setRowHeight(Table table, int height) {
        if (table == null || table.isDisposed()) {
            return;
        }

        // 关键修正：不直接调用setItemHeight，而是通过设置字体大小间接调整行高
        // 计算需要的字体高度（行高 - 上下边距）
        int fontHeight = Math.max(10, height - 6); // 6px边距
        FontData[] fontData = table.getFont().getFontData();
        for (FontData data : fontData) {
            data.setHeight(fontHeight);
        }
        table.setFont(new Font(table.getDisplay(), fontData));
    }

    /**
     * 自动调整列宽以适应内容
     * @param table 目标表格
     */
    public static void packAllColumns(Table table) {
        if (table == null || table.isDisposed()) {
            return;
        }

        for (TableColumn column : table.getColumns()) {
            column.pack();
        }
    }


    // ====================== 3. 表格数据操作 ======================

    /**
     * 向表格添加一行数据
     * @param table 目标表格
     * @param data 行数据数组（长度应与列数一致）
     * @return 添加的行对象（null表示失败）
     */
    public static TableItem addRow(Table table, String[] data) {
        if (table == null || table.isDisposed() || data == null) {
            return null;
        }

        TableItem item = new TableItem(table, SWT.NONE);
        setRowData(table, item, data); // 安全设置行数据
        return item;
    }

    /**
     * 批量添加行数据
     * @param table 目标表格
     * @param data 二维数组，每个子数组代表一行数据
     */
    public static void addRows(Table table, String[][] data) {
        if (table == null || table.isDisposed() || data == null) {
            return;
        }

        for (String[] rowData : data) {
            addRow(table, rowData);
        }
    }

    /**
     * 设置行数据（自动处理数据长度与列数不匹配的情况）
     * @param table 目标表格
     * @param item 行对象
     * @param data 行数据数组
     */
    public static void setRowData(Table table, TableItem item, String[] data) {
        if (table == null || table.isDisposed() || item == null || item.isDisposed() || data == null) {
            return;
        }

        int columnCount = getColumnCount(table);
        String[] safeData = new String[columnCount];
        
        // 填充数据，超出列数的部分忽略，不足的部分用空字符串补充
        for (int i = 0; i < columnCount; i++) {
            safeData[i] = (i < data.length) ? (data[i] == null ? "" : data[i]) : "";
        }
        
        item.setText(safeData);
    }

    /**
     * 设置单元格数据
     * @param table 目标表格
     * @param rowIndex 行索引
     * @param columnIndex 列索引
     * @param data 单元格数据
     */
    public static void setCellData(Table table, int rowIndex, int columnIndex, String data) {
        if (table == null || table.isDisposed() || rowIndex < 0 || columnIndex < 0) {
            return;
        }

        TableItem item = getRowItem(table, rowIndex);
        if (item == null) {
            return;
        }

        // 安全处理null数据
        String safeData = data == null ? "" : data;
        item.setText(columnIndex, safeData);
    }

    /**
     * 获取单元格数据
     * @param table 目标表格
     * @param rowIndex 行索引
     * @param columnIndex 列索引
     * @return 单元格数据（非null，默认空字符串）
     */
    public static String getCellData(Table table, int rowIndex, int columnIndex) {
        if (table == null || table.isDisposed() || rowIndex < 0 || columnIndex < 0) {
            return "";
        }

        TableItem item = getRowItem(table, rowIndex);
        if (item == null) {
            return "";
        }

        String data = item.getText(columnIndex);
        return data == null ? "" : data;
    }

    /**
     * 清空表格数据（保留表头）
     * @param table 目标表格
     */
    public static void clearTableData(Table table) {
        if (table == null || table.isDisposed()) {
            return;
        }

        table.removeAll();
    }

    /**
     * 删除指定行
     * @param table 目标表格
     * @param rowIndex 行索引
     */
    public static void deleteRow(Table table, int rowIndex) {
        if (table == null || table.isDisposed() || rowIndex < 0 || rowIndex >= getRowCount(table)) {
            return;
        }

        table.remove(rowIndex);
    }


    // ====================== 4. 表格权限控制 ======================

    /**
     * 设置表格是否可编辑（整体控制）
     * @param table 目标表格
     * @param editable true=可编辑，false=只读
     */
    public static void setTableEditable(Table table, boolean editable) {
        if (table == null || table.isDisposed()) {
            return;
        }

        // SWT表格本身没有直接的editable属性，通过设置选择监听器控制编辑行为
        if (!editable) {
            table.addSelectionListener(new SelectionAdapter() {
                @Override
                public void widgetSelected(SelectionEvent e) {
                    // 只读模式下取消选择事件
                    e.doit = false;
                }
            });
        }
    }

    /**
     * 设置整列只读/可编辑（修正后：无警告且功能正常）
     * @param table 目标表格
     * @param columnIndex 列索引
     * @param readOnly true=只读，false=可编辑
     */
    public static void setColumnReadOnly(Table table, int columnIndex, boolean readOnly) {
        if (table == null || table.isDisposed() || columnIndex < 0 || columnIndex >= getColumnCount(table)) {
            return;
        }

        // 为表格添加选择监听器，控制特定列的编辑权限
        table.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                // 1. 只处理TableItem的点击事件（排除表头、空白区域等）
                if (e.item instanceof TableItem) {
                    // 2. 获取当前点击的列索引（核心：通过Table的选择索引判断）
                    int clickedColumnIndex = table.getSelectionIndex();
                    // 3. 只有点击目标列时，才执行只读控制
                    if (clickedColumnIndex == columnIndex) {
                        e.doit = !readOnly; // 只读时禁用事件，可编辑时允许事件
                    }
                }
            }
        });
    }

    /**
     * 设置整行只读/可编辑
     * @param table 目标表格
     * @param rowIndex 行索引
     * @param readOnly true=只读，false=可编辑
     */
    public static void setRowReadOnly(Table table, int rowIndex, boolean readOnly) {
        if (table == null || table.isDisposed() || rowIndex < 0 || rowIndex >= getRowCount(table)) {
            return;
        }

        TableItem item = getRowItem(table, rowIndex);
        if (item == null) {
            return;
        }

        // 为TableItem设置背景色区分只读行（浅灰色）
        if (readOnly) {
            Color gray = new Color(table.getDisplay(), 240, 240, 240);
            item.setBackground(gray);
            // 注册释放监听，避免内存泄漏
            item.addDisposeListener(e -> gray.dispose());
        } else {
            item.setBackground(null); // 恢复默认背景
        }

        // 添加选择监听器控制编辑权限
        table.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                if (e.item == item) {
                    e.doit = !readOnly; // 只读时取消事件
                }
            }
        });
    }

    /**
     * 设置单元格只读/可编辑
     * @param table 目标表格
     * @param rowIndex 行索引
     * @param columnIndex 列索引
     * @param readOnly true=只读，false=可编辑
     */
    public static void setCellReadOnly(Table table, int rowIndex, int columnIndex, boolean readOnly) {
        if (table == null || table.isDisposed() || rowIndex < 0 || columnIndex < 0 || 
            rowIndex >= getRowCount(table) || columnIndex >= getColumnCount(table)) {
            return;
        }

        // 修正警告：显式声明final，确保匿名内部类引用有效，消除“未使用”误判
        final TableItem item = getRowItem(table, rowIndex);
        if (item == null) {
            return;
        }

        // 添加选择监听器控制编辑权限（此处item被e.item == item引用，确认为使用）
        table.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                // 修正逻辑：e.widget是Table，需通过Table.getItem()判断列索引，原逻辑有误
                if (e.item == item) {
                    // 获取点击的列索引
                    int clickColumnIndex = table.indexOf(table.getColumn(columnIndex));
                    // 判断是否点击目标列（通过Table的getColumnOrder获取实际列序）
                    if (table.getColumn(clickColumnIndex) == table.getColumn(columnIndex)) {
                        e.doit = !readOnly; // 只读时取消事件
                    }
                }
            }
        });
    }

    // ====================== 5. 表格信息获取 ======================

    /**
     * 获取表格列数
     * @param table 目标表格
     * @return 列数（异常时返回0）
     */
    public static int getColumnCount(Table table) {
        if (table == null || table.isDisposed()) {
            return 0;
        }
        return table.getColumnCount();
    }

    /**
     * 获取表格行数
     * @param table 目标表格
     * @return 行数（异常时返回0）
     */
    public static int getRowCount(Table table) {
        if (table == null || table.isDisposed()) {
            return 0;
        }
        return table.getItemCount();
    }

    /**
     * 获取指定行的TableItem对象
     * @param table 目标表格
     * @param rowIndex 行索引
     * @return TableItem对象（null表示失败）
     */
    public static TableItem getRowItem(Table table, int rowIndex) {
        if (table == null || table.isDisposed() || rowIndex < 0 || rowIndex >= table.getItemCount()) {
            return null;
        }
        return table.getItem(rowIndex);
    }

    /**
     * 获取选中的行索引数组
     * @param table 目标表格
     * @return 选中行的索引数组（无选中时返回空数组）
     */
    public static int[] getSelectedRowIndices(Table table) {
        if (table == null || table.isDisposed()) {
            return new int[0];
        }

        TableItem[] selectedItems = table.getSelection();
        int[] indices = new int[selectedItems.length];
        
        for (int i = 0; i < selectedItems.length; i++) {
            indices[i] = table.indexOf(selectedItems[i]);
        }
        
        return indices;
    }

    // ====================== 6. 表格事件处理 ======================

    /**
     * 为表格添加选择事件监听器
     * @param table 目标表格
     * @param listener 事件监听器
     */
    public static void addSelectionListener(Table table, SelectionAdapter listener) {
        if (table == null || table.isDisposed() || listener == null) {
            return;
        }

        table.addSelectionListener(listener);
    }

    /**
     * 为表格列添加点击事件监听器（可用于排序）
     * @param table 目标表格
     * @param columnIndex 列索引
     * @param listener 事件监听器
     */
    public static void addColumnClickListener(Table table, int columnIndex, SelectionAdapter listener) {
        if (table == null || table.isDisposed() || columnIndex < 0 || columnIndex >= getColumnCount(table) || listener == null) {
            return;
        }

        table.getColumn(columnIndex).addSelectionListener(listener);
    }


    // ====================== 7. 工具方法 ======================

    /**
     * 安全释放TableColumn（TableColumn是Item类型，不是Control）
     */
    private static void safeDisposeTableColumn(TableColumn column) {
        if (column != null && !column.isDisposed()) {
            column.dispose();
        }
    }

    /**
     * 通过字体计算行高（避免使用setItemHeight）
     * @param table 目标表格
     * @return 行高（像素）
     */
    private static int getRowHeightByFont(Table table) {
        // 字体高度 + 上下边距（6px）
        return table.getFont().getFontData()[0].getHeight() + 6;
    }
}